# !/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author : 大野

from common.log import Log
import json
import common.info_error as excep
import interface.testCase.asserts.db_check as dbcheck

logger = Log()
null = None


class ResponseCodeCheck:

    def checkdb(self, info, code):
        '''
        数据库断言
        :param info:数据库查询结果
        :param code: 预期结果
        :return:
        '''
        logger.info(f"数据库输入检查数据------{type(info),info}----预期结果---{code}")
        if isinstance(info, dict):
            if bool(self.__checkdict(info, code)):
                return excep.db_assert_info(info)
            else:
                return excep.db_assert_err_exception(info)
        elif isinstance(info, list):
            if bool(self.__checklist(info, code)):
                return excep.db_assert_info(info)
            else:
                return excep.db_assert_err_exception(info)
        else:
            return excep.db_assert_err_exception(info)

    def resp_check(self, info, code, respTime, infoCode):
        '''
        实际结果和预期结果断言
        :param info: 实际响应结果
        :param code: 预期结果
        :param respTime: 响应时间
        :param infoCode: 响应码
        :return:
        '''
        infoJson = info.json()
        infoText = info.text
        if isinstance(infoJson, dict):
            if bool(self.__checkdict(infoJson, code)):
                return excep.assert_info(infoText, respTime, code)
            else:
                return excep.assert_err_exception(infoText, respTime, infoCode)
        elif isinstance(infoJson, list):
            if bool(self.__checklist(infoJson, code)):
                return excep.assert_info(infoText, respTime, infoCode)
            else:
                return excep.assert_err_exception(infoText, respTime, infoCode)

    def __checklist(self, info, code):
        '''
        检查列表
        :param info: 接口响应
        :param code: 预期结果
        :return:
        '''
        try:
            for i in code:
                if isinstance(i, str) or isinstance(i, int):
                    if i in info:
                        continue
                    else:
                        return False
                for j in info:
                    if isinstance(i, dict):
                        if bool(self.__checkdict(j, i)):
                            break
                        else:
                            return False
                    elif isinstance(i, list):
                        if bool(self.__checklist(j, i)):
                            break
                        else:
                            return False
                    break
                else:
                    return False
            return True
        except Exception as e:
            return False

    def __checkdict(self, info, code):
        '''
        检查json
        :param info:接口响应
        :param code: 预期结果
        :return:
        '''
        try:
            for k, v in code.items():
                for k2, v2 in info.items():
                    if k == k2:
                        if isinstance(v2, list):
                            if bool(self.__checklist(v2, v)):
                                break
                            else:
                                return False
                        elif isinstance(v2, dict):
                            if bool(self.__checkdict(v2, v)):
                                break
                            else:
                                return False
                        elif v == v2:
                            break
                        else:
                            return False
                    else:
                        continue
                else:
                    return False
            return True
        except Exception as e:
            return False

    # 根据http响应码对比
    def http_code(self, info, infocode, respTime, case):
        infoText = info.text
        if case["case_check"] is None:
            return excep.assert_err_exception(infoText, respTime, infocode)
        elif infocode == int(case["case_check"]):
            return excep.assert_info(infoText, respTime, infocode)
        else:
            return excep.assert_err_exception(infoText, respTime, infocode)

    def db_case(self, data, case, project):
        try:
            if data["success"] == "true" and case["template_param"] != '':
                db_info = dbcheck.case_db(project, case["template_param"])
                if isinstance(db_info, list):
                    if len(db_info) > 0:
                        from common.timeJson import ComplexEncoder
                        logger.info(f"SQL执行结果----【开始序列化】---{db_info}")
                        db_inf = json.dumps(db_info[0], cls=ComplexEncoder)
                        logger.info(f"SQL执行结果----【序列化结束】---{db_inf}")
                        if case['template_check']:
                            db_code = json.loads(case['template_check'])
                            db_check_result = self.checkdb(eval(db_inf), db_code)
                            logger.info(f"-------{db_check_result}")
                            return self.__dictdata(data, db_check_result)
                        else:
                            db_check_result = excep.case_check_error()
                            return self.__dictdata(data, db_check_result)
                    else:
                        db_check_result = excep.db_select_null(db_info, case["template_check"])
                        return self.__dictdata(data, db_check_result)
                elif isinstance(db_info, dict):
                    from common.timeJson import ComplexEncoder
                    logger.info(f"SQL执行结果----【开始序列化】---{db_info}")
                    db_inf = json.dumps(db_info, cls=ComplexEncoder)
                    logger.info(f"SQL执行结果----【序列化结束】---{db_inf}")
                    if case['template_check']:
                        db_code = json.loads(case['template_check'])
                        db_check_result = self.checkdb(eval(db_inf), db_code)
                        logger.info(f"-------{db_check_result}")
                        return self.__dictdata(data, db_check_result)
                    else:
                        db_check_result = excep.case_check_error()
                        return self.__dictdata(data, db_check_result)
                else:
                    db_res = excep.db_start_true()
                    return self.__dictdata(data, db_res)
            elif data["success"] == "true" and case["template_param"] == '':
                db_check_result = excep.db_param_null()
                return self.__dictdata(data, db_check_result)
            else:
                db_check_result = excep.case_result_error()
                return self.__dictdata(data, db_check_result)
        except Exception as e:
            db_check_result = excep.case_db_error(e)
            return self.__dictdata(data, db_check_result)

    # 自定义断言
    def code_all(self, info, infocode, respTime, case, project):
        if case["case_check"] in ['200', '201', '204', '206']:
            data = self.http_code(info, infocode, respTime, case)
            return self.db_case(data, case, project)
        else:
            code = json.loads(case['case_check'])
            data = self.resp_check(info, code, respTime, infocode)
            logger.info(f"接口测试结果>>>>>>{data}")
            return self.db_case(data, case, project)

    def __dictdata(self, data, db_check_result):
        return {**data, **db_check_result}


if __name__ == '__main__':
    resp = "数据处理完成"
    code = {"valid_point": 0, "total_invalidByRefund_point": 20, "invalidByRefund_point": 20}
    print(ResponseCodeCheck().checkdb(resp,code))